import {
  list, detail, update, create, remove, getBuild,
  saveBuild, outputAPIDemo, outputResultDemo
} from '../services/datasource';
import { basicInfo as indexDetail } from '../services/index';
import { detail as appDetail } from '../services/app';

import { stateCreate, effectsCreate, reducers, dataHandle } from 'src/models/modelCreator';
import { systemConstants } from 'src/utils/constants';

function* buildConfigHandle({ data, error }, { put }) {
  if (data) {
    yield put({
      type: 'buildConfigSuccess',
      payload: data,
    });
  }
  else if (error && error.fieldErrors) {
    yield put({
      type: 'putError',
      payload: {
        fieldErrors: error.fieldErrors,
      }
    });
  }
}

export default {
    namespace: 'datasource',
    state: {
      ...stateCreate(),
      entity: {
        fullDatasourceType: 0,
        incDatasourceType: -1
      },
      moduleName: 'datasource',
      entityDescription: '数据源',
      searchParams: {},
      relatedData: {
        appData: {},
        indexData: {}
      },
      buildConfig: {
        cron: ''
      },
      fullApiDemoResponse: {},
      fullTestResponse: {},
      incApiDemoResponse: {},
      incTestResponse: {},
      incCallbackDemoResponse: {},
      currentFullStep: 0,
    },

    effects: {
      ...effectsCreate({ list, detail, update, create, remove }, dataHandle),

      * list({ payload, }, { call, put, select }) {
        const searchParams = yield select(state => state[payload.module]['searchParams']);
        const { data, error } = yield call(list, searchParams);
        yield dataHandle.nakeListHandle({ data, error }, { put });
      },

      * saveDetail({ payload, }, { call, put, select }) {
        const searchParams = yield select(state => state[payload.module]['searchParams']);
        const param = { ...payload.param, indexId: searchParams.indexId };
        const {data, error } = payload.param.id
          ? yield call(update, param)
          : yield call(create, param);
        yield dataHandle.saveDetailFinishHandle({ data, error }, { put });
        if (!error) {
          yield put({
            type: 'list',
            payload: { module: payload.module },
          });
        }
      },

      * deleteItem({ payload, }, { call, put, select }) {
        const { data, error } = yield call(remove, payload.id);
        yield dataHandle.deleteHandle({ data, error }, { put });
        if (!error) {
          yield put({
            type: 'list',
            payload: { module: payload.module },
          });
        }
      },

      * relatedData({ payload, }, { call, put, select }) {
        const {projectId, indexId} = yield select(state => state[payload.module]['searchParams']);

        const appDetailReq = call(appDetail, projectId);
        const indexDetailReq = call(indexDetail, indexId);
        const buildConfigReq = call(getBuild, indexId);

        const appResp = yield appDetailReq;
        const indexResp = yield indexDetailReq;
        const buildConfigResp = yield buildConfigReq;

        const { data, error } = {
          data: { appData: appResp.data, indexData: indexResp.data, buildConfig: buildConfigResp.data },
          error: appResp.error || indexResp.error || buildConfigResp.error
        };
        yield dataHandle.relatedDataHandle({ data, error }, { put });
      },

      * saveBuildConfig({ payload, }, { call, put, select }) {
        const {data, error } = yield call(saveBuild, payload);
        yield buildConfigHandle({ data, error }, { put });
      },

      * outputAPIDemo({ payload, }, { call, put, select }) {
        const {data, error } = yield call(outputAPIDemo, payload);
        if (data) {
          yield put({
            type: 'outputAPIDemoSuccess',
            payload: {
              ...data,
              ...payload,
            }
          });
        }
        else if (error && error.fieldErrors) {
          yield put({
            type: 'putError',
            payload: {
              fieldErrors: error.fieldErrors,
            }
          });
        }
      },

      * triggerTest({ payload, }, { call, put, select }) {
        const {data, error } = yield call(outputResultDemo, payload);
        if (data) {
          yield put({
            type: 'triggerTestSuccess',
            payload: {
              ...data,
              ...payload,
            }
          });
        }
        else if (error && error.fieldErrors) {
          yield put({
            type: 'putError',
            payload: {
              fieldErrors: error.fieldErrors,
            }
          });
        }
      },
    },

    subscriptions: {
      setup({ history, dispatch }) {
        // 监听 history 变化，当进入 `/` 时触发 `load` action
        return history.listen(({ pathname, query }) => {
          dispatch({
            type: 'paramsChange',
            payload: query
          });

          if (pathname.match(/\/datasource/)) {
            dispatch({
              type: 'list',
              payload: { module: 'datasource' }
            });

            dispatch({
              type: 'relatedData',
              payload: { module: 'datasource' }
            });
          }
        });
      },
    },
    reducers: {
      ...reducers,

      clearApiResults(state, action) {
        let type = action.payload;
        if (type === 'full') {
          return {
            ...state,
            fullApiDemoResponse: {},
            fullTestResponse: {},
            currentFullStep: 0
          };
        }
        else if (type === 'inc') {
          return {
            ...state,
            incApiDemoResponse: {},
            incTestResponse: {},
            incCallbackDemoResponse: {},
            currentIncStep: 0
          }
        }
      },

      triggerTestSuccess(state, action) {

        let response = action.payload;
        if (response.type === 'full') {
          return {
            ...state,
            fullApiDemoResponse: {},
            fullTestResponse: response,
            currentFullStep: 2
          };
        }
        else if (response.type === 'incCallback') {
          return {
            ...state,
            incApiDemoResponse: {},
            incCallbackDemoResponse: {},
            incTestResponse: response,
            currentIncStep: 3
          };
        }
      },

      outputAPIDemoSuccess(state, action) {
        let response = action.payload;
        if (response.type === 'full') {
          return {
            ...state,
            fullApiDemoResponse: response,
            currentFullStep: 1
          };
        }
        else if (response.type === 'inc') {
          return {
            ...state,
            incApiDemoResponse: response,
            currentIncStep: 1
          };
        }
        else if (response.type === 'incCallback') {
          return {
            ...state,
            incApiDemoResponse: {},
            incCallbackDemoResponse: response,
            currentIncStep: 2
          };
        }
      },

      changeIncImportType(state, action) {
        return {
          ...state,
          entity: {
            ...state.entity,
            incDatasourceType: action.payload ? 0 : -1,
            useIncImport: action.payload
          }
        }
      },

      relatedDataSuccess(state, action) {
        const {appData, indexData, buildConfig } = action.payload;
        return {
          ...state,
          relatedData: {
            appData,
            indexData
          },
          buildConfig
        };
      },

      buildConfigSuccess(state, action) {
        const buildConfig = action.payload;
        return {
          ...state,
          buildConfig
        };
      },

      loadDetailSuccess(state, action) {
        const { incDatasourceType } = action.payload;
        return {
          ...state,
          entity: {
            ...action.payload,
            useIncImport: incDatasourceType === -1 ? false : true
          }
        };
      },

      closeDetailModal(state) {
        return {
          ...state,
          entity: {},
          fullApiDemoResponse: {},
          fullTestResponse: {},
          incApiDemoResponse: {},
          incTestResponse: {},
          incCallbackDemoResponse: {},
          currentFullStep: 0,
          showDetailModal: false
        }
      },
    }
}
